//
//  JMPhotosManager.m
//  ImagePicker
//
//  Created by Jamin on 2018/10/15.
//  Copyright © 2018 jamin. All rights reserved.
//

#import "JMPhotosManager.h"

#import "JMImagePickerDefines.h"
#import "UIImage+JMIP.h"

const CGFloat JMIPCurrentScreenScale = 2.0;

@interface JMPhotosManager () {
    BOOL _notScaleImage;
    
}

@end

@implementation JMPhotosManager

+ (JMPhotosManager *)manager {
    static JMPhotosManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[self alloc] init];
    });
    return manager;
}

/// Return YES if Authorized 返回YES如果得到了授权
+ (BOOL)authorizationStatusAuthorized {
    NSInteger status = [self authorizationStatus];
    if (status == 0) {
        [self requestAuthorization:NULL];
    }
    
    return status == 3;
}

+ (NSInteger)authorizationStatus {
    return [PHPhotoLibrary authorizationStatus];
}

+ (void)requestAuthorization:(void(^)())completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            dispatch_async(dispatch_get_main_queue(), ^{
                !completion ?: completion();
            });
        }];
    });
}

+ (void)getAlbumListWithcompletion:(void(^)(NSArray <JMIPAlbum *>*albums))completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        PHFetchOptions *option = [[PHFetchOptions alloc] init];
        PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
        
        NSMutableArray *list = [NSMutableArray array];
        for (PHAssetCollection *collection in smartAlbums) {
            // 有可能是PHCollectionList类的的对象，过滤掉
            if (![collection isKindOfClass:[PHAssetCollection class]]) continue;
            // 过滤空相册
            if (collection.estimatedAssetCount <= 0) continue;

            PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:option];
            if (fetchResult.count <= 0) continue;
//                model = [self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:YES needFetchAssets:needFetchAssets];
            JMIPAlbum *model = [[JMIPAlbum alloc] initWithCollection:collection result:fetchResult];
            [list addObject:model];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            !completion ?: completion(list.copy);
        });
    });
}

+ (void)getAblumThumbnailImage:(JMIPAlbum *)album completion:(void (^)(UIImage *image))completion {
    id asset = [album.result lastObject];
//    if (!self.sortAscendingByModificationDate) {
//        asset = [model.result firstObject];
//    }
    [self getPhotoWithAsset:asset photoWidth:JMIPAssetThumbnailSize.width completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
        if (completion) completion(photo);
    }];
}


#pragma mark - Get Assets

/// Get Assets 获得照片数组
+ (void)getAssetsFromFetchResult:(PHFetchResult *)result
                      completion:(void (^)(NSArray<JMIPAsset *> *assets))completion {
//    TZImagePickerConfig *config = [TZImagePickerConfig sharedInstance];
    return [self getAssetsFromFetchResult:result
                               allowVideo:YES
                               allowImage:YES
                               completion:completion];
}

+ (void)getAssetsFromFetchResult:(PHFetchResult *)result
                      allowVideo:(BOOL)allowVideo
                      allowImage:(BOOL)allowImage
                      completion:(void (^)(NSArray<JMIPAsset *> *assets))completion {
    NSMutableArray *photoArr = [NSMutableArray array];
    [result enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL * _Nonnull stop) {
        JMIPAsset *model = [JMIPAsset assetWithAsset:asset];
//        [self assetModelWithAsset:asset allowPickingVideo:allowPickingVideo allowPickingImage:allowPickingImage];
        if (model) [photoArr addObject:model];
    }];
    !completion ?: completion(photoArr.copy);
}

///  Get asset at index 获得下标为index的单个照片
///  if index beyond bounds, return nil in callback 如果索引越界, 在回调中返回 nil
+ (void)getAssetFromFetchResult:(PHFetchResult *)result
                        atIndex:(NSInteger)index
                     allowImage:(BOOL)allowImage
                     completion:(void (^)(JMIPAsset *asset))completion {
    PHAsset *asset;
    @try {
        asset = result[index];
    }
    @catch (NSException* e) {
        if (completion) completion(nil);
        return;
    }
    JMIPAsset *model = [JMIPAsset assetWithAsset:asset]; //[self assetModelWithAsset:asset allowPickingVideo:allowPickingVideo allowPickingImage:allowPickingImage];
    !completion ?: completion(model);
}

+ (int32_t)getPhotoWithAsset:(PHAsset *)asset
                  photoWidth:(CGFloat)photoWidth
                  completion:(void (^)(UIImage *photo, NSDictionary *info, BOOL isDegraded))completion {
    return [self getPhotoWithAsset:asset photoWidth:photoWidth completion:completion progressHandler:nil networkAccessAllowed:YES];
}


+ (int32_t)getPhotoWithAsset:(PHAsset *)asset
                  photoWidth:(CGFloat)photoWidth
                  completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion
             progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler
        networkAccessAllowed:(BOOL)networkAccessAllowed {
    CGSize imageSize;
    if (photoWidth < [UIScreen mainScreen].bounds.size.width && photoWidth < 600.0) {
        imageSize = JMIPAssetThumbnailSize;
    } else {
        PHAsset *phAsset = (PHAsset *)asset;
        CGFloat aspectRatio = phAsset.pixelWidth / (CGFloat)phAsset.pixelHeight;
        CGFloat pixelWidth = photoWidth * JMIPCurrentScreenScale * 1.5;
        // 超宽图片
        if (aspectRatio > 1.8) {
            pixelWidth = pixelWidth * aspectRatio;
        }
        // 超高图片
        if (aspectRatio < 0.2) {
            pixelWidth = pixelWidth * 0.5;
        }
        CGFloat pixelHeight = pixelWidth / aspectRatio;
        imageSize = CGSizeMake(pixelWidth, pixelHeight);
    }
    
    __block UIImage *image;
    // 修复获取图片时出现的瞬间内存过高问题
    // 下面两行代码，来自hsjcom，他的github是：https://github.com/hsjcom 表示感谢
    PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
    option.resizeMode = PHImageRequestOptionsResizeModeFast;
    int32_t imageRequestID = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:imageSize contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage *result, NSDictionary *info) {
        if (result) {
            image = result;
        }
        BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);
        if (downloadFinined && result) {
//            result = [self fixOrientation:result];
            if (completion) completion(result,info,[[info objectForKey:PHImageResultIsDegradedKey] boolValue]);
            return ;
        }
        // Download image from iCloud / 从iCloud下载图片
        if ([info objectForKey:PHImageResultIsInCloudKey] && !result && networkAccessAllowed) {
            PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
            options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (progressHandler) {
                        progressHandler(progress, error, stop, info);
                    }
                });
            };
            options.networkAccessAllowed = YES;
            options.resizeMode = PHImageRequestOptionsResizeModeFast;
            [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
                UIImage *resultImage = [UIImage imageWithData:imageData];
                if (![self notScaleImage]) {
                    resultImage = [resultImage jmip_imageResize:imageSize];
                }
                
                if (!resultImage) {
                    resultImage = image;
                }
//                resultImage = [self fixOrientation:resultImage];
                if (completion) completion(resultImage,info,NO);
            }];
        }
    }];
    return imageRequestID;
}

+ (void)setNotScaleImage:(BOOL)notScaleImage {
    [self manager]->_notScaleImage = notScaleImage;
}
+ (BOOL)notScaleImage {
    return [self manager]->_notScaleImage;
}



@end
